import {
  Injectable,
  NotFoundException,
  ConflictException,
  BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Singer } from './singer.entity';
import {
  CreateSingerDto,
  UpdateSingerDto,
  SingerResponseDto,
  SingersPaginationQueryDto,
} from './singer.dto';
import { Song } from '../song/song.entity';
import { PaginationResponseDto } from '../song/song.dto';
import { AvatarUploadService } from '../common/services/avatar-upload.service';

@Injectable()
export class SingerService {
  constructor(
    @InjectRepository(Singer)
    private singerRepository: Repository<Singer>,
    @InjectRepository(Song)
    private songRepository: Repository<Song>,
    private readonly avatarUploadService: AvatarUploadService,
  ) {}

  // 将歌手实体映射为响应DTO
  private mapToResponseDto(singer: Singer): SingerResponseDto {
    const dto = new SingerResponseDto();
    dto.id = singer.id;
    dto.name = singer.name;
    // 描述可能有很长，这里截断到1000个字符
    dto.description = singer.description?.substring(0, 100) || '';
    dto.avatarUrl = singer.avatarUrl;
    dto.birthDate = singer.birthDate;
    dto.nationality = singer.nationality;
    dto.createdAt = singer.createdAt;
    dto.updatedAt = singer.updatedAt;
    dto.gender = singer.gender;
    dto.type = singer.type;

    // 映射专辑数据
    dto.albums =
      singer.albums?.map((album) => ({
        id: album.id,
        title: album.title,
        artist: {
          id: singer.id,
          name: singer.name,
        },
        releaseDate: album.releaseDate,
        coverImageUrl: album.coverImageUrl,
        description: album.description,
        plays: album.plays,
        songs: [],
        createdAt: album.createdAt,
        updatedAt: album.updatedAt,
      })) || [];

    // 映射歌曲数据
    dto.songs =
      singer.songs?.map((song) => ({
        id: song.id,
        title: song.title,
        artist: {
          id: singer.id,
          name: singer.name,
        },
        album: song.album
          ? {
              id: song.album.id,
              title: song.album.title,
            }
          : undefined,
        genre: song.genre,
        duration: song.duration,
        audioUrl: song.audioUrl,
        coverImageUrl: song.album?.coverImageUrl || song.coverImageUrl,
        lyrics: song.lyrics,
        plays: song.plays,
        likes: 0, // 这里可以根据需要修改
        createdAt: song.createdAt,
        updatedAt: song.updatedAt,
        uploadedBy: undefined, // 这里可以根据需要修改
        categories: [], // 这里可以根据需要修改
      })) || [];

    return dto;
  }

  // 创建新歌手
  async createSinger(
    createSingerDto: CreateSingerDto,
  ): Promise<SingerResponseDto> {
    // 检查歌手名称是否已存在
    const existingSinger = await this.singerRepository.findOneBy({
      name: createSingerDto.name,
    });
    if (existingSinger) {
      throw new ConflictException(`歌手名称 "${createSingerDto.name}" 已存在`);
    }

    const singer = this.singerRepository.create(createSingerDto);
    const savedSinger = await this.singerRepository.save(singer);
    return this.mapToResponseDto(savedSinger);
  }

  // 获取所有歌手（支持分页）
  async getAllSingers(
    query: SingersPaginationQueryDto,
  ): Promise<PaginationResponseDto<SingerResponseDto>> {
    const page = query.page || 1;
    const limit = query.limit || 10;
    const skip = (page - 1) * limit;

    // 构建查询条件
    const queryBuilder = this.singerRepository.createQueryBuilder('singer');

    // 添加过滤条件
    if (query.type) {
      queryBuilder.where('singer.type = :type', { type: query.type });
    }

    if (query.gender) {
      queryBuilder.andWhere('singer.gender = :gender', {
        gender: query.gender,
      });
    }

    if (query.nationality) {
      queryBuilder.andWhere('singer.nationality = :nationality', {
        nationality: query.nationality,
      });
    }

    // 执行查询
    const [singers, total] = await queryBuilder
      .skip(skip)
      .take(limit)
      .getManyAndCount();

    const totalPages = Math.ceil(total / limit);

    return {
      data: singers.map((singer) => this.mapToResponseDto(singer)),
      meta: {
        total,
        page,
        limit,
        totalPages,
        hasNextPage: page < totalPages,
        hasPreviousPage: page > 1,
      },
    };
  }

  // 获取单个歌手
  async getSingerById(id: number): Promise<SingerResponseDto> {
    const singer = await this.singerRepository.findOne({
      where: { id },
      relations: ['songs', 'albums', 'songs.album'],
    });
    if (!singer) {
      throw new NotFoundException(`歌手ID ${id} 不存在`);
    }
    return this.mapToResponseDto(singer);
  }

  // 更新歌手
  async updateSinger(
    id: number,
    updateSingerDto: UpdateSingerDto,
  ): Promise<SingerResponseDto> {
    const singer = await this.singerRepository.findOneBy({ id });
    if (!singer) {
      throw new NotFoundException(`歌手ID ${id} 不存在`);
    }

    // 检查新的歌手名称是否已存在（如果提供了新名称）
    if (updateSingerDto.name && updateSingerDto.name !== singer.name) {
      const existingSinger = await this.singerRepository.findOneBy({
        name: updateSingerDto.name,
      });
      if (existingSinger) {
        throw new ConflictException(
          `歌手名称 "${updateSingerDto.name}" 已存在`,
        );
      }
    }

    // 更新歌手信息
    Object.assign(singer, updateSingerDto);
    const updatedSinger = await this.singerRepository.save(singer);
    return this.mapToResponseDto(updatedSinger);
  }

  // 删除歌手
  async deleteSinger(id: number): Promise<void> {
    const result = await this.singerRepository.delete(id);
    if (result.affected === 0) {
      throw new NotFoundException(`歌手ID ${id} 不存在`);
    }
  }

  // 获取歌手的所有歌曲
  async getSongsBySinger(id: number): Promise<Song[]> {
    const singer = await this.singerRepository.findOne({
      where: { id },
      relations: ['songs'],
    });
    if (!singer) {
      throw new NotFoundException(`歌手ID ${id} 不存在`);
    }
    return singer.songs;
  }

  // 搜索歌手
  async searchSingers(keyword: string): Promise<SingerResponseDto[]> {
    const singers = await this.singerRepository
      .createQueryBuilder('singer')
      .where('singer.name LIKE :keyword', { keyword: `%${keyword}%` })
      .orWhere('singer.description LIKE :keyword', { keyword: `%${keyword}%` })
      .orWhere('singer.nationality LIKE :keyword', { keyword: `%${keyword}%` })
      .getMany();
    return singers.map((singer) => this.mapToResponseDto(singer));
  }

  // 上传歌手头像
  async uploadSingerAvatar(
    id: number,
    file: Express.Multer.File,
  ): Promise<{ avatarUrl: string }> {
    // 查找歌手
    const singer = await this.singerRepository.findOneBy({ id });
    if (!singer) {
      throw new NotFoundException(`歌手ID ${id} 不存在`);
    }

    // 如果歌手已有头像，先删除旧头像
    if (singer.avatarUrl) {
      try {
        await this.avatarUploadService.deleteOldAvatar(singer.avatarUrl);
      } catch (error) {
        // 删除旧头像失败不影响新头像上传
        console.warn('删除旧头像文件失败:', error.message);
      }
    }

    // 保存新头像并获取URL
    const avatarUrl = await this.avatarUploadService.saveAvatar(file);

    // 更新歌手的头像URL
    singer.avatarUrl = avatarUrl;
    await this.singerRepository.save(singer);

    return { avatarUrl };
  }
}
